package com.android.sharecar.activity;

import java.util.ArrayList;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;

/**
 * 普通状态，默认界面
 * @author xinyan
 *@date 2011-9-13
 */
public class StandardActivity extends MapActivity {
	private static final String TAG = "StandardActivity";

	// state of user
	// USER SEND A REQUEST AND WAITING FOR MATCH,
	// DISPLAY CANCEL_PICKRIDE BUTTON
	private static final int STATE_WAITING_FOR_RIDE = 1;

	// USER GET A RIDE, DISPLAY GET_IN_CAR BUTTON
	private static final int STATE_MATCH_SUCCESS = 2;

	// USER HAVE GET IN CAR, DISPLAY GET_OFF_CAR BUTTON
	private static final int STATE_ON_THE_WAY = 3;
	private static final int STATE_NORMAL = 0;

	// user's current state
	private static int mCurrentState = STATE_NORMAL;

	// Static things related with mapview
	private MapController mMapController;
	private MyLocationOverlay mMyPosition;
	private MapView mMapView;
	private GeoPoint mGeoPoint;

	private Drawable marker;

	// Buttons in mapview
	private Button mMyLocationButton, mSatelliteMode, mTrafficMode;

	// Views statement.
	private ImageView mHeadPic;
	private TextView mPost1, mPost2;
	private Button mCancelPickRide, mGetInCar, mGetOffCar;

	// Temporary members for imitation of match request success.
	// we don't match, just send a success msg.
	private static Handler mHandler = null;
	private static Runnable mRunnable = null;

	// vars for pin a touch point
	long start = 0, stop = 0;
	int x, y;
	GeoPoint touchPoint = null;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.standard);

		Log.v(TAG, "After setContentView, we gonna to findViews.");
		findViews();

		// get intent then get the state from it.
		Intent intent = getIntent();
		Bundle bundle = intent.getExtras();

		// May be need try catch here.
		if (bundle.containsKey("state")) {
			mCurrentState = bundle.getInt("state");
			Log.v(TAG, "Current state code is: " + mCurrentState);
		}

		Log.v(TAG, "gonna to setListenerForViews");
		setListenerForViews();
		Log.v(TAG, "gonna to showStateButton");
		showStateButton();

		LocationManager locationManager;

		locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

		// get controller instance to control the map
		mMapController = mMapView.getController();

		// set presentation mode.
		mMapView.setStreetView(true);
		mMapView.setTraffic(true);
		// mMapView.displayZoomControls(true);
		mMapView.setBuiltInZoomControls(true);
		mMapView.setEnabled(true);
		mMapView.setClickable(true);

		//

		// 获取标记图片： marker.png
		marker = getResources().getDrawable(R.drawable.marker);
		// 设置图片的绘制区域大小
		marker.setBounds(0, 0, marker.getIntrinsicWidth(),
				marker.getIntrinsicHeight());

		TouchOverlay touchy = new TouchOverlay();
		mMapView.getOverlays().add(touchy);

		/*// set Criteria(Provider) information
		Criteria criteria = new Criteria();
		criteria.setAccuracy(Criteria.ACCURACY_FINE);
		criteria.setAltitudeRequired(false);
		criteria.setBearingRequired(false);
		criteria.setCostAllowed(false);
		criteria.setPowerRequirement(Criteria.POWER_LOW);

		String provider = locationManager.getBestProvider(criteria, true);*/
		String provider = LocationManager.NETWORK_PROVIDER;
		Location location = locationManager.getLastKnownLocation(provider);
		Log.v(TAG, "The last know location is:" + location.toString());
		mMyPosition = new MyLocationOverlay();
		mMyPosition.setLocation(location);
		mMapView.getOverlays().add(mMyPosition);
		updateWithNewLocation(location);
		locationManager.requestLocationUpdates(provider, 3000, 0,
				mLocationListener);
	}

	private void findViews() {
		mHeadPic = (ImageView) findViewById(R.id.standard_iv_headPic);
		mPost1 = (TextView) findViewById(R.id.standard_tv_post1);
		mPost2 = (TextView) findViewById(R.id.standard_tv_post2);

		mCancelPickRide = (Button) findViewById(R.id.standard_btn_cancel_pickride);
		mGetInCar = (Button) findViewById(R.id.standard_btn_get_in_car);
		mGetOffCar = (Button) findViewById(R.id.standard_btn_get_off_car);

		mMyLocationButton = new Button(this);
		/*mTrafficMode = new Button(this);
		mSatelliteMode = new Button(this);*/

		mMyLocationButton.setText("我的位置");
		/*mTrafficMode.setText("交通");
		mSatelliteMode.setText("卫星");*/

		mMapView = (MapView) findViewById(R.id.standard_map_main);
		MapView.LayoutParams paramsMyLocation = new MapView.LayoutParams(
				ViewGroup.LayoutParams.WRAP_CONTENT,
				ViewGroup.LayoutParams.WRAP_CONTENT, 200, 100,
				MapView.LayoutParams.CENTER_HORIZONTAL);
		mMapView.addView(mMyLocationButton, paramsMyLocation);
	}

	/**
	 * This method will show the appropriate button on the top of Activity
	 *  related with the current state code(mCurrentState).
	 */
	private void showStateButton() {

		switch (mCurrentState) {
		case STATE_MATCH_SUCCESS:
			mCancelPickRide.setVisibility(View.GONE);
			mGetInCar.setVisibility(View.VISIBLE);
			mGetOffCar.setVisibility(View.GONE);
			Log.v(TAG, "Current state code is: " + mCurrentState);

			return;
		case STATE_ON_THE_WAY:
			mCancelPickRide.setVisibility(View.GONE);
			mGetInCar.setVisibility(View.GONE);
			mGetOffCar.setVisibility(View.VISIBLE);
			Log.v(TAG, "Current state code is: " + mCurrentState);

			return;
		case STATE_WAITING_FOR_RIDE:
			mCancelPickRide.setVisibility(View.VISIBLE);
			mGetInCar.setVisibility(View.GONE);
			mGetOffCar.setVisibility(View.GONE);
			Log.v(TAG, "Current state code is: " + mCurrentState);

			// The following code is about to imitate a pick ride success event.
			if (null == mHandler) {
				Log.v(TAG, "Now we are going to new a Handle object.");

				mHandler = new Handler() {

					@Override
					public void handleMessage(Message msg) {
						switch (msg.what) {
						case 1:
							mCancelPickRide.setVisibility(View.GONE);
							mGetInCar.setVisibility(View.VISIBLE);
							mGetOffCar.setVisibility(View.GONE);

							Log.v(TAG,
									"3 seconds later, match success and GetInCar button should visible now.");
							break;
						default:
							break;
						}

						super.handleMessage(msg);
					}
				};
			}

			if (null == mRunnable) {
				Log.v(TAG, "Now we are going to new a Runnable interface.");

				mRunnable = new Runnable() {

					@Override
					public void run() {
						mHandler.sendEmptyMessage(1);// 向Handler发送空消息
						Log.v(TAG, "Message has been send, wait for 3 seconds.");

					}
				};
			}
			mHandler.postDelayed(mRunnable, 3000);// 5s后执行

			return;
		case STATE_NORMAL:
			mCancelPickRide.setVisibility(View.GONE);
			mGetInCar.setVisibility(View.GONE);
			mGetOffCar.setVisibility(View.GONE);
			Log.v(TAG, "Current state code is: " + mCurrentState);

			return;
		}
	}

	private void setListenerForViews() {
		mMyLocationButton.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				Double geoLat = mMyPosition.mLocation.getLatitude();
				Double geoLon = mMyPosition.mLocation.getLongitude();
				/*mMapController.animateTo(new GeoPoint(geoLat.intValue(), geoLon
						.intValue()));*/
				mMapController.setCenter(new GeoPoint(geoLat.intValue(), geoLon
						.intValue()));
			}
		});

		mHeadPic.setOnTouchListener(new View.OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				if (MotionEvent.ACTION_DOWN == event.getAction()) {
					startActivity(new Intent(StandardActivity.this,
							UserInfo_MeActivity.class));

				}
				return true;
			}
		});

		mCancelPickRide.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				mCancelPickRide.setVisibility(View.GONE);
				mGetInCar.setVisibility(View.GONE);
				mGetOffCar.setVisibility(View.GONE);

				return;
			}
		});

		mGetInCar.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				startActivity(new Intent(StandardActivity.this,
						ConfirmCarInfoActivity.class));
			}
		});

		mGetOffCar.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				startActivity(new Intent(StandardActivity.this,
						EvaluationActivity.class));
			}
		});
	}

	private void updateWithNewLocation(Location location) {
		String latLongString;

		if (location != null) {
			mMyPosition.setLocation(location);
			Double geoLat = location.getLatitude() * 1E6;
			Double geoLng = location.getLongitude() * 1E6;
			GeoPoint point = new GeoPoint(geoLat.intValue(), geoLng.intValue());
			mMapController.animateTo(point);

			// Display a fake user
			GeoPoint fakePoint = new GeoPoint(geoLat.intValue() + 5000,
					geoLng.intValue() + 5000);
			OverlayItem fakeItem = new OverlayItem(fakePoint, "fake user",
					"fake point");
			CustomPoint custom = new CustomPoint(marker, this);
			custom.insertPinpoint(fakeItem);
			mMapView.getOverlays().add(custom);
		} else {
			latLongString = "无法获取您的当前地址";
		}
	}

	@Override
	protected boolean isRouteDisplayed() {
		// TODO Auto-generated method stub
		return false;
	}

	/**
	 * This is class for touch event ,when user touched the screen for 
	 * enough time, user can tag the touched place as user's favorite
	 * place, or fix current position and set as destination.
	 * @author xinyan
	 *@date 2011-10-10
	 */
	class TouchOverlay extends Overlay {

		@Override
		public boolean onTouchEvent(MotionEvent e, MapView mapView) {
			Log.v(TAG, "Touchy is touched...");

			if (MotionEvent.ACTION_DOWN == e.getAction()) {
				start = e.getEventTime();
				x = (int) e.getX();
				y = (int) e.getY();
				touchPoint = mMapView.getProjection().fromPixels(x, y);
				Log.v(TAG, "Touchy is touched.. and we get touch point.");
			}
			if (MotionEvent.ACTION_UP == e.getAction()) {
				stop = e.getEventTime();
			}
			if (stop - start > 1500) {
				OverlayItem overlayItem = new OverlayItem(touchPoint,
						"Pined position", "A new position");
				CustomPoint custom = new CustomPoint(marker,
						StandardActivity.this);
				custom.insertPinpoint(overlayItem);
				mMapView.getOverlays().add(custom);

				new AlertDialog.Builder(StandardActivity.this)
						.setIcon(null)
						.setTitle(R.string.whatYouWant)
						.setSingleChoiceItems(
								R.array.select_dialog_whatYouWant, 0,
								new DialogInterface.OnClickListener() {
									@Override
									public void onClick(DialogInterface dialog,
											int whichButton) {

										if (0 == whichButton) {

											// user clicked fix my current
											// position choice
										} else if (1 == whichButton) {

											// user clicked set as destination
											// choice
										}
									}
								})
						.setPositiveButton(R.string.positive,
								new DialogInterface.OnClickListener() {
									@Override
									public void onClick(DialogInterface dialog,
											int whichButton) {

										if (0 == whichButton) {

											// user clicked fix my current
											// position choice
										} else if (1 == whichButton) {

											// user clicked set as destination
											// choice

										} else if (3 == whichButton) {

											// user clicked put into favorite
											// choice
										}
									}
								})
						.setNegativeButton(R.string.cancel,
								new DialogInterface.OnClickListener() {
									@Override
									public void onClick(DialogInterface dialog,
											int whichButton) {

										dialog.dismiss();
									}
								}).create().show();
			} // end of if (stop - start > 1500)
			else {
				// I think this overrided method shouldn't capture all
				// of the touch events, otherwise we can't control the map.
				return false;
			}
			return true;
		}

	}

	private final LocationListener mLocationListener = new LocationListener() {
		@Override
		public void onLocationChanged(Location location) {
			updateWithNewLocation(location);
		}

		@Override
		public void onProviderDisabled(String provider) {
			updateWithNewLocation(null);
		}

		@Override
		public void onProviderEnabled(String provider) {
		}

		@Override
		public void onStatusChanged(String provider, int status, Bundle extras) {
		}
	};

	class MyLocationOverlay extends Overlay {
		Location mLocation;

		public void setLocation(Location location) {
			mLocation = location;
		}

		@Override
		public boolean draw(Canvas canvas, MapView mapView, boolean shadow,
				long when) {
			super.draw(canvas, mapView, shadow);
			Paint paint = new Paint();
			Point myScreenCoords = new Point();
			GeoPoint tmpGeoPoint;
			if (null != mLocation) {
				tmpGeoPoint = new GeoPoint(
						(int) (mLocation.getLatitude() * 1E6),
						(int) (mLocation.getLongitude() * 1E6));
				mapView.getProjection().toPixels(tmpGeoPoint, myScreenCoords);
				paint.setStrokeWidth(1);
				paint.setARGB(255, 255, 0, 0);
				paint.setStyle(Paint.Style.STROKE);
				BitmapDrawable bmpDrawable = (BitmapDrawable) getResources()
						.getDrawable(R.drawable.mylocation);
				Bitmap bmp = bmpDrawable.getBitmap();
				if (null != bmp) {
					canvas.drawBitmap(bmp, myScreenCoords.x, myScreenCoords.y,
							paint);
				}
				canvas.drawText("我在这里", myScreenCoords.x, myScreenCoords.y,
						paint);
			} else {
				return false;
			}

			return true;
		}
	}

	/**
	 * This is a custom class of pin point overlay,
	 * it means this overlay appears a marker when you click a place on 
	 * the mapview. The StandardActivtiy will use it. 
	 * @author xinyan
	 *@date 2011-10-9
	 *
	 */
	class CustomPoint extends ItemizedOverlay<OverlayItem> {
		private final ArrayList<OverlayItem> pinpoints = new ArrayList<OverlayItem>();
		private Context c;

		public CustomPoint(Drawable defaultMarker) {
			super(defaultMarker);
			// TODO Auto-generated constructor stub
		}

		public CustomPoint(Drawable marker, Context context) {
			this(marker);
			c = context;
		}

		@Override
		protected OverlayItem createItem(int i) {
			return pinpoints.get(i);
		}

		@Override
		public int size() {
			return pinpoints.size();
		}

		public void insertPinpoint(OverlayItem item) {
			pinpoints.add(item);
			this.populate();
		}

		@Override
		public boolean onTap(GeoPoint p, MapView mapView) {
			// TODO Auto-generated method stub
			return super.onTap(p, mapView);
		}

		@Override
		protected boolean onTap(int index) {
			startActivity(new Intent(StandardActivity.this,
					UserInfo_OthersActivity.class));
			return true;
		}
	}

	/*class WalmartLocations extends ItemizedOverlay {

		List<OverlayItem> items = new ArrayList<OverlayItem>();
		Drawable marker;

		public WalmartLocations(Drawable marker) {
			super(marker);
			this.marker = marker;

			// 找出厦门3个沃尔玛的经纬度 构造确定点 GeoPoint来表示他们的位置
			// 24.477384,118.158216
			GeoPoint wal1 = new GeoPoint((int) (24.477384 * 1000000),
					(int) (118.158216 * 1000000));

			// 24.468967,118.114277
			GeoPoint wal2 = new GeoPoint((int) (24.468967 * 1000000),
					(int) (118.114277 * 1000000));

			// 24.501091,118.126781
			GeoPoint wal3 = new GeoPoint((int) (24.501091 * 1000000),
					(int) (118.126781 * 1000000));

			// 将GeoPoint 添加到Overlay中
			items.add(new OverlayItem(wal1, "沃尔玛购物广场(洪文分店)", "地处瑞景商业广场对面"));
			items.add(new OverlayItem(wal2, "沃尔玛购物广场", "火车站附近"));
			items.add(new OverlayItem(wal3, "沃尔玛", "扁食嫂和麦当劳"));

			// 这行代码很重要，就是将Overlay层的标记显示出来
			populate();

		}

		@Override
		public void draw(Canvas canvas, MapView mapView, boolean shadow) {
			super.draw(canvas, mapView, shadow);

			// 显示图标，图标位置在目标点下面，居中的位置
			boundCenterBottom(marker);
		}

		@Override
		protected OverlayItem createItem(int i) {
			return items.get(i);
		}

		@Override
		public int size() {
			return items.size();
		}

		@Override
		protected boolean onTap(int index) {
			OverlayItem item = items.get(index);
			startActivity(new Intent(StandardActivity.this,
					UserInfo_OthersActivity.class));
			AlertDialog.Builder dialog = new AlertDialog.Builder(
					StandardActivity.this);
			dialog.setTitle(item.getTitle());
			dialog.setMessage(item.getSnippet());
			dialog.show();
			return true;
		}

	}*/
}
